<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        /* 清除默认样式 */
        * {
            margin: 0;
            padding: 0;
        }
        ul,
        li {
            list-style: none;
        }
        a {
            text-decoration: none;
        }
        input {
            outline: none;
        }
        .clearfix:after {
            content: "";
            display: block;
            clear: both;
        }

        /* 元素的我水平垂直居中有几种方式? */
        /* 容器 */
        #box {
            position: absolute;
            left: 0;
            top: 0;
            right: 0;
            bottom: 0;
            margin: auto;
            width: 600px;
            height: 337px;
            overflow: hidden;
        }
        /* 图片列表 */
        .list {
            position: absolute;
            left: -600px;
            width: 3600px;
            height: 337px;
        }
        .item {
            float: left;
            width: 600px;
            height: 337px;
        }
        .item img {
            width: 600px;
            height: 337px;
        }

        /* 切换图片上下按钮 */
        #box > span {
            position: absolute;
            display: block;
            width: 20px;
            height: 60px;
            line-height: 60px;
            background-color: rgba(90, 90, 90, 0.8);
            top: 50%;
            transform: translateY(-50%);
            text-align: center;
            color: #fff;
            cursor: pointer;
            opacity: 0;
            transition: all .7s;
        }

        /*
        问: 
        1. 过渡可以给哪些属性加? 一般是连续的值的时候可以加过渡
        2. 过渡过程中的值可以拿到吗? 值是瞬变的,效果是渐变的,过渡过程中的值是拿不到的
        */
        .prev {
            left: 0;
        }
        .next {
            right: 0;
        }
        /* 小圆点 */
        .iconlist {
            position: absolute;
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%);
            display: flex;
        }
        .iconitem {
            width: 20px;
            height: 20px;
            background-color: rgba(90, 90, 90, 0.8);
            margin: 0 10px;
            border-radius: 50%;
        }
        .active {
            background-color: rgba(66, 199, 223, 0.8);
        }
    </style>
</head>

<body>

    <!-- 容器 -->
    <div id="box">
        <!-- 图片列表 -->
        <ul class="list">
            <li class="item"><img src="./img/004.jpg"></li>
            <li class="item"><img src="./img/001.jpg"></li>
            <li class="item"><img src="./img/002.jpg"></li>
            <li class="item"><img src="./img/003.jpg"></li>
            <li class="item"><img src="./img/004.jpg"></li>
            <li class="item"><img src="./img/001.jpg"></li>
        </ul>
        <!-- 上下按钮 -->
        <span class="prev"> < </span>
        <span class="next"> > </span>
        <!-- 小圆点:分页器 -->
        <ul class="iconlist">
            <li class="iconitem active"></li>
            <li class="iconitem"></li>
            <li class="iconitem"></li>
            <li class="iconitem"></li>
        </ul>
    </div>

    <script>
        var box = document.getElementById('box'); // 容器
        var prev = document.querySelector('.prev'); // 上一页按钮
        var next = document.querySelector('.next'); // 下一页按钮
        var list = document.querySelector('.list'); // 图片列表
        var iconitems = document.querySelectorAll('.iconitem'); // 获取4个小圆点

        var distTime = 20; // 每次移动时间间隔
        var timer = null; // 存储移动图片列表的定时器
        var isRun = false;// 存图片移动的定时器(timer)是否运行,如果是运行中,再次点击按钮切换页面应该不让在生成定时器
        var autoPlayTime = null; // 存储自动播放的定时器

        autoPlay(); // 自动播放
        function autoPlay () {
            autoPlayTimer = setInterval(function () {
                move(true);
            }, 2000)
        }

        // 小圆点点击事件
        // 循环给每个小圆点绑定点击事件
        for (var i = 0; i < iconitems.length; i++) {

            iconitems[i].index = i; // 在DOM对象上暂存一下当前的这个下标

            iconitems[i].onclick = function () {
                // 1. 小圆点颜色跟着点击的变化
                // 排他思想
                for (var j = 0; j < iconitems.length; j++) {
                    iconitems[j].className = 'iconitem';
                }
                this.className = 'iconitem active';
                // 2. 图片跟着变,首先算偏移量
                // console.log( this.index );
                // console.log( (this.index + 1) * -600 );

                // 起始位置
                var startX = list.offsetLeft;
                // 结束位置
                var endX = (this.index + 1) * -600;
                // 距离差
                var dist = endX - startX;
                // 我们的move函数中,只有距离差在变化,其他都不变,逻辑可以拿过来直接用
                // 想办法把距离差传进move函数中去即可
                move(dist);
            }
        }

        next.onclick = function () {
            move(true)
        }

        prev.onclick = function () {
            move(false)
        }

        // 封装移动图片列表函数,之后点击按钮直接调用这个函数即可
        // 通过参数的形式来判断点击的是上一页还是下一页
        function move (flag) {
            if (isRun) {
                return;
            }
            isRun = true; // 代表开始移动
            if (typeof flag === 'number') {
                var dist = flag;
            } else {
                if (flag) {
                    var dist = -600;
                } else {
                    var dist = 600;
                }
            }
            // 起始位置
            var startX = list.offsetLeft;
            // 距离差
            // var dist = -600;
            // 结束位置
            var endX = startX + dist;
            // 每次移动的距离:步长
            var step = dist / distTime; // 这里刚刚我们只是计算了一下结束的位置

            // 每隔固定时间移动一次图片列表
            timer = setInterval(function() {
                // 每次移完的位置 = 每次移动的距离 + 当前位置
                list.style.left = step + list.offsetLeft + 'px';
                // 上一行代码已经移动完成了,此时取list.offsetLeft就是移动完成的值
                // 当移动到下一张图片的时候,让定时器停止
                // 判断当前图片位置和刚刚计算的结束位置相等为结束条件
                if (list.offsetLeft == endX) {
                    clearInterval(timer);
                    isRun = false; //  移动完毕变成false,代表已经移动完毕
                    // 当移动完成的时候,判断是不是应该瞬变
                    if (list.offsetLeft === -3000) {
                        list.style.left = -600 + 'px';
                    } else if (list.offsetLeft === 0) {
                        list.style.left = -2400 + 'px';
                    }
                }
            }, distTime)
        
            // 小圆点跟随:图片移动的时候,小圆点发生跟随
            // 排他思想
            for (var i = 0; i < iconitems.length; i++) {
                iconitems[i].className = 'iconitem'
            }
            // 获取当前的小圆点下标
            var idx = endX / -600  - 1; // 下标
            // 对边界条件进行处理
            // console.log('修复前',  endX, idx  );
            if (idx == 4) {
                idx = 0;
            } else if (idx == -1) {
                idx = 3;
            }
            // console.log('修复后',  endX, idx  );
            iconitems[idx].className = 'iconitem active';

        }
        // 当图片瞬变,如果是同一张图片的话,人眼无法识别


        // 鼠标移入移出
        box.onmouseenter = function () {
            prev.style.opacity = 1;
            next.style.opacity = 1;
            // 清除自动播放的定时器
            clearInterval(autoPlayTimer);
        }
        box.onmouseleave = function () {
            prev.style.opacity = 0;
            next.style.opacity = 0;

            autoPlay();
        }


        // 过程:
        // 1. 搭建静态页面(一遍)
        // 2. 上下翻页按钮移入移出渐变事件绑定
        // 3. 点击上下按钮切换图片
        //      3.1 算出起始位置
        //      3.2 算出距离差(下一页 -600 上一页 600)
        //      3.3 算出结束位置
        //      3.4 算出步长
        //      3.5 写定时器,让图片列表每次移动步长的距离
        //      3.6 当图片列表移动到结束位置的时候,停掉定时器
        // 4. 封装 move 函数,点击上下按钮,执行move函数即可
        // 5. 无缝切换
        //      我们呢总共4长图片,分别是
        //      1 2 3 4
        //      在1前面加一个4,在4后面加一个1,此时我们的图片变成6张
        //      4 1 2 3 4 1
        //      默认显示1(-600px)
        //      当图片列表移动到最后一个1的时候,瞬间切换到前面的1
        //      当图片列表移动到第一个4的时候,瞬间切换到后面4
        //      这个过程在清除定时器的时候,取瞬变
        // 6. 小圆点跟随
        //      当图片发生给改变的时候,小圆点高亮应该跟随改变
        //      小圆点高亮我们只变一次,在定时器中不合适,move函数是图片列表移动,在move函数中写逻辑
        //      使用排他思想
        //      让所有的小圆点变成灰色,当前小圆点(根据结束位置取算当前是第几个小圆点)变成高亮
        // 7. 小圆点点击事件
        //      拿到所有的小圆点,循环绑定点击事件
        //      7.1 让小圆点高亮随着点击而变化
        //      7.2 图片跟着小圆点变
        //          逻辑和图片移动move函数的逻辑一样,直接使用move函数
        // 8. 定时器叠加问题
        //      全局声明一个布尔值来控制,当图片列表移动过程中,此时为true,移动完成为false
        //      当是true的时候,再次调用move函数应该直接退出return
        // 9. 自动播放
        //      封装一个函数,调用这个函数自动播放
        //      函数中有个定时器来控制自动播放
        //      当鼠标移入容器的时候,清除定时器
        //      当鼠标移出容器的时候,调用这个函数
        //      默认情况下手动调用一个这个函数

    </script>

</body>

</html>